# pragma once

# include <string>
# include "cpp_tools.h"
# include "tinyxml2.h"
# include "filePathSettings.h"
# include "XmlParameterManager.h"

using namespace tinyxml2;

// 默认设置
namespace udpSettings
{
    namespace IP
    {
        std::string upper = "127.0.0.1"; // 上位机IP

        std::string lower = "127.0.0.1"; // 下位机IP

        std::string solver = "127.0.0.1"; // 求解器IP

        std::string sim = "127.0.0.1"; // 仿真环境IP
    };
    
    namespace PORT
    {
        namespace upper_lower
        {
            // int order = 25000; // 上位机向下位机发送指令
            // int order_len = 10;

            // int info = 25001; // 下位机返回消息
            // int info_len = 10;

            int plot = 25002; // lower返回状态消息
            int plot_len = 12;
        };
        
        namespace lower_solver
        {
            int order = 25100; // 下位机发送指令
            int order_len = 5e3;

            int message = 25101; // 求解器返回消息
            int message_len = 5e3;
        };
        
        namespace lower_sim
        {
            int steering = 25200; // 向仿真环境发送的转向
            int steering_len = 1;

            int drive = 25201; // 向仿真环境发送的驱动力
            int drive_len = 1;

            int state = 25202; // 仿真环境发送的状态量
            int state_len = 10;
        };
    };

    /// @brief 使用int传输double数据时缩放的大小
    /// 
    /// double*intScale -> int 发送
    /// 
    /// int -> double/intScale 接收
    /// 
    /// 不能太大否则数据会溢出
    int intScale = 1e5;
};

using namespace udpSettings;
namespace RC_udp
{
    std::string path = host_path + settings_path + "/udp/";
    std::string fileName = "settings.xml";
    std::string xmlFilePath = path + fileName;

    /// @brief 读取xml文件并赋值给全局变量
    /// @param genIfEmpty 如果没有xml文件是否新建一个
    void readXML(bool genIfEmpty = 1)
    {
        try
        {
            cpp_tools::XmlParameterManager m_xml("udpSettings", xmlFilePath);
            bool writeXML = false;

            // 读取IP设置
            if (!m_xml.getParameter("IP", "upper", IP::upper))
            {
                std::cout << "上位机IP使用默认值: " << IP::upper << std::endl;
                m_xml.setParameter("IP", "upper", IP::upper);
                writeXML = true;
            }

            if (!m_xml.getParameter("IP", "lower", IP::lower))
            {
                std::cout << "下位机IP使用默认值: " << IP::lower << std::endl;
                m_xml.setParameter("IP", "lower", IP::lower);
                writeXML = true;
            }

            if (!m_xml.getParameter("IP", "solver", IP::solver))
            {
                std::cout << "求解器IP使用默认值: " << IP::solver << std::endl;
                m_xml.setParameter("IP", "solver", IP::solver);
                writeXML = true;
            }

            if (!m_xml.getParameter("IP", "sim", IP::sim))
            {
                std::cout << "仿真环境IP使用默认值: " << IP::sim << std::endl;
                m_xml.setParameter("IP", "sim", IP::sim);
                writeXML = true;
            }

            // 读取PORT.upper_lower设置
            if (!m_xml.getParameter("PORT/upper_lower", "plot", PORT::upper_lower::plot))
            {
                std::cout << "upper_lower.plot端口使用默认值: " << PORT::upper_lower::plot << std::endl;
                m_xml.setParameter("PORT/upper_lower", "plot", PORT::upper_lower::plot);
                writeXML = true;
            }

            if (!m_xml.getParameter("PORT/upper_lower", "plot_len", PORT::upper_lower::plot_len))
            {
                std::cout << "upper_lower.plot_len使用默认值: " << PORT::upper_lower::plot_len << std::endl;
                m_xml.setParameter("PORT/upper_lower", "plot_len", PORT::upper_lower::plot_len);
                writeXML = true;
            }

            // 读取PORT.lower_solver设置
            if (!m_xml.getParameter("PORT/lower_solver", "order", PORT::lower_solver::order))
            {
                std::cout << "lower_solver.order端口使用默认值: " << PORT::lower_solver::order << std::endl;
                m_xml.setParameter("PORT/lower_solver", "order", PORT::lower_solver::order);
                writeXML = true;
            }

            if (!m_xml.getParameter("PORT/lower_solver", "order_len", PORT::lower_solver::order_len))
            {
                std::cout << "lower_solver.order_len使用默认值: " << PORT::lower_solver::order_len << std::endl;
                m_xml.setParameter("PORT/lower_solver", "order_len", PORT::lower_solver::order_len);
                writeXML = true;
            }

            if (!m_xml.getParameter("PORT/lower_solver", "message", PORT::lower_solver::message))
            {
                std::cout << "lower_solver.message端口使用默认值: " << PORT::lower_solver::message << std::endl;
                m_xml.setParameter("PORT/lower_solver", "message", PORT::lower_solver::message);
                writeXML = true;
            }

            if (!m_xml.getParameter("PORT/lower_solver", "message_len", PORT::lower_solver::message_len))
            {
                std::cout << "lower_solver.message_len使用默认值: " << PORT::lower_solver::message_len << std::endl;
                m_xml.setParameter("PORT/lower_solver", "message_len", PORT::lower_solver::message_len);
                writeXML = true;
            }

            // 读取PORT.lower_sim设置
            if (!m_xml.getParameter("PORT/lower_sim", "steering", PORT::lower_sim::steering))
            {
                std::cout << "lower_sim.steering端口使用默认值: " << PORT::lower_sim::steering << std::endl;
                m_xml.setParameter("PORT/lower_sim", "steering", PORT::lower_sim::steering);
                writeXML = true;
            }

            if (!m_xml.getParameter("PORT/lower_sim", "steering_len", PORT::lower_sim::steering_len))
            {
                std::cout << "lower_sim.steering_len使用默认值: " << PORT::lower_sim::steering_len << std::endl;
                m_xml.setParameter("PORT/lower_sim", "steering_len", PORT::lower_sim::steering_len);
                writeXML = true;
            }

            if (!m_xml.getParameter("PORT/lower_sim", "drive", PORT::lower_sim::drive))
            {
                std::cout << "lower_sim.drive端口使用默认值: " << PORT::lower_sim::drive << std::endl;
                m_xml.setParameter("PORT/lower_sim", "drive", PORT::lower_sim::drive);
                writeXML = true;
            }

            if (!m_xml.getParameter("PORT/lower_sim", "drive_len", PORT::lower_sim::drive_len))
            {
                std::cout << "lower_sim.drive_len使用默认值: " << PORT::lower_sim::drive_len << std::endl;
                m_xml.setParameter("PORT/lower_sim", "drive_len", PORT::lower_sim::drive_len);
                writeXML = true;
            }

            if (!m_xml.getParameter("PORT/lower_sim", "state", PORT::lower_sim::state))
            {
                std::cout << "lower_sim.state端口使用默认值: " << PORT::lower_sim::state << std::endl;
                m_xml.setParameter("PORT/lower_sim", "state", PORT::lower_sim::state);
                writeXML = true;
            }

            if (!m_xml.getParameter("PORT/lower_sim", "state_len", PORT::lower_sim::state_len))
            {
                std::cout << "lower_sim.state_len使用默认值: " << PORT::lower_sim::state_len << std::endl;
                m_xml.setParameter("PORT/lower_sim", "state_len", PORT::lower_sim::state_len);
                writeXML = true;
            }

            // 如果有任何默认值被设置，保存到XML文件
            if (writeXML)
            {
                m_xml.saveToFile(xmlFilePath);
            }
        }
        catch (const std::exception& e)
        {
            std::cerr << "加载UDP设置时发生错误: " << e.what() << std::endl;
        }
    }
} // namespace udp
